package com.example.backend.utils;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Supplier;

public class ThreadContext {
    /**
     * 使用ThreadLocal存储数据映射
     */
    private static final ThreadLocal<Map<String, Object>> CONTEXT =
            ThreadLocal.withInitial(HashMap::new);

    /**
     * 私有构造函数，防止实例化
     */
    private ThreadContext() {
    }

    /**
     * 设置一个值到当前线程的上下文中
     *
     * @param key   键
     * @param value 值
     */
    public static void put(String key, Object value) {
        CONTEXT.get().put(key, value);
    }

    /**
     * 获取当前线程中的值
     *
     * @param key 键
     * @return 值
     */
    public static Object get(String key) {
        return CONTEXT.get().get(key);
    }

    /**
     * 从当前线程的上下文中获取值，并转换为指定类型
     *
     * @param key   键
     * @param clazz 目标类型
     * @param <T>   泛型类型
     * @return 值，可能为null
     */
    @SuppressWarnings("unchecked")
    public static <T> T get(String key, Class<T> clazz) {
        return (T) CONTEXT.get().get(key);
    }

    /**
     * 从当前线程的上下文中获取值，如果不存在则使用提供的默认值
     *
     * @param key          键
     * @param defaultValue 默认值提供者
     * @param <T>          泛型类型
     * @return 值
     */
    @SuppressWarnings("unchecked")
    public static <T> T getOrDefault(String key, Supplier<T> defaultValue) {
        Map<String, Object> map = CONTEXT.get();
        return (T) map.computeIfAbsent(key, k -> defaultValue.get());
    }

    /**
     * 检查当前线程的上下文中是否包含某个键
     *
     * @param key 键
     * @return 是否包含
     */
    public static boolean containsKey(String key) {
        return CONTEXT.get().containsKey(key);
    }

    /**
     * 从当前线程的上下文中移除一个键值对
     *
     * @param key 键
     * @return 被移除的值，可能为null
     */
    public static Object remove(String key) {
        return CONTEXT.get().remove(key);
    }

    /**
     * 清除当前线程的上下文
     */
    public static void clear() {
        CONTEXT.get().clear();
    }

    /**
     * 完全移除当前线程的上下文（谨慎使用，可能导致内存泄漏）
     */
    public static void remove() {
        CONTEXT.remove();
    }

    /**
     * 获取当前线程上下文的大小
     *
     * @return 上下文大小
     */
    public static int size() {
        return CONTEXT.get().size();
    }

    /**
     * 判断当前线程上下文是否为空
     *
     * @return 是否为空
     */
    public static boolean isEmpty() {
        return CONTEXT.get().isEmpty();
    }
}
